package com.ctshk.rpc.season.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SeasonType;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.air.dto.AirProductPriceDTO;
import com.ctshk.rpc.air.dto.AirProductPriceTouristDTO;
import com.ctshk.rpc.air.dto.ProductFullPriceAndStockDTO;
import com.ctshk.rpc.air.dto.ProductFullPriceDTO;
import com.ctshk.rpc.air.dto.app.AirProductDetailDTO;
import com.ctshk.rpc.air.req.AirProductCostQueryReq;
import com.ctshk.rpc.air.req.ProductFullPriceReq;
import com.ctshk.rpc.air.service.IAirProductCostService;
import com.ctshk.rpc.air.service.app.IAirProductAppService;
import com.ctshk.rpc.season.dto.CabinClassDTO;
import com.ctshk.rpc.season.dto.PackageProductCostDTO;
import com.ctshk.rpc.season.dto.SeasonFixedProductPackageAirDTO;
import com.ctshk.rpc.season.entity.SeasonFixedProductPackageAir;
import com.ctshk.rpc.season.mapper.SeasonFixedProductPackageAirMapper;
import com.ctshk.rpc.season.req.PassengerReq;
import com.ctshk.rpc.season.req.SeasonFixedProductPackageAirReq;
import com.ctshk.rpc.season.req.UpdatePackageProductReq;
import com.ctshk.rpc.season.service.ISeasonFixedProductPackageAirService;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 套票-固定套票单项产品打包-机票表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-09
 */
@Slf4j
@DubboService
public class SeasonFixedProductPackageAirServiceImpl extends ServiceImpl<SeasonFixedProductPackageAirMapper, SeasonFixedProductPackageAir> implements ISeasonFixedProductPackageAirService {
    @DubboReference
    private IAirProductCostService airProductCostService;
    @DubboReference
    private IAirProductAppService iAirProductAppService;


    @Autowired
    private SeasonFixedProductPackageAirMapper seasonFixedProductPackageAirMapper;

    /* @MethodName: 获取机票的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/26 17:10
     **/
    @Override
    public PackageProductCostDTO getAirProductPrice(Long productId, LocalDate departureDate, Long userId, Integer channelType) {
        PackageProductCostDTO costDto = new PackageProductCostDTO();
        try {
            SeasonType seasonTypeEnum = SeasonType.getEnumType(channelType, null);
            List<Long> touristTypes = new ArrayList<>();
            touristTypes.add(Long.parseLong(SeasonType.ADULT.getKey()));
            touristTypes.add(Long.parseLong(SeasonType.CHILD.getKey()));
            switch (seasonTypeEnum) {
                //线下自营的方式
                case OFFLINE_SELF_CHANNEL_TYPE:
                    AirProductCostQueryReq queryReq = new AirProductCostQueryReq();
                    queryReq.setStarDate(departureDate);//日期
                    //queryReq.setEndDate(priceReq.getQueryDate());//日期
                    queryReq.setProductIds(Arrays.asList(productId));//产品id
                    queryReq.setRelationId(userId); //关联id
                    queryReq.setChannelType(channelType);
                    queryReq.setTouristTypeIds(touristTypes);
                    List<AirProductPriceDTO> costPriceDTOList = airProductCostService.queryProductCost(queryReq);
                    if (null != costPriceDTOList && costPriceDTOList.size() > 0) {
                        AirProductPriceDTO airProductPriceDTO = costPriceDTOList.get(0);
                        if (null != airProductPriceDTO && null != airProductPriceDTO.getAirProductPriceTouristDTOList() && airProductPriceDTO.getAirProductPriceTouristDTOList().size() > 0) {
                            for (AirProductPriceTouristDTO cost : airProductPriceDTO.getAirProductPriceTouristDTOList()) {
                                if (cost.getAirTouristTypeId().intValue() == SeasonType.ADULT.getCode()) {
                                    costDto.setCostPrice(cost.getAirProductPriceDateDTOList().get(0).getPrice());
                                }
                                if (cost.getAirTouristTypeId().intValue() == SeasonType.CHILD.getCode()) {
                                    costDto.setChildPrice(cost.getAirProductPriceDateDTOList().get(0).getPrice());
                                }
                            }
                        }
                    }
                    break;
                //线上渠道
                case ONLINE_SELF_CHANNEL_TYPE:
                    ProductFullPriceReq productFullPriceReq = new ProductFullPriceReq();
                    productFullPriceReq.setChannelId(userId);
                    productFullPriceReq.setDate(departureDate);
                    productFullPriceReq.setProductId(productId);
                    productFullPriceReq.setTouristTypes(touristTypes);
                    log.info("调用机票服务获取价格入参", productFullPriceReq);
                    ProductFullPriceAndStockDTO productFullPriceAndStockDTO = iAirProductAppService.getProductFullPrice(productFullPriceReq);
                    log.info("调用机票服务获取价格值", productFullPriceAndStockDTO);
                    if (null != productFullPriceAndStockDTO && productFullPriceAndStockDTO.getStock() > 0) {
                        for (ProductFullPriceDTO cost : productFullPriceAndStockDTO.getList()) {
                            if (cost.getTouristType().intValue() == SeasonType.ADULT.getCode()) {
                                costDto.setCostPrice(cost.getPrice());
                            }
                            if (cost.getTouristType().intValue() == SeasonType.CHILD.getCode()) {
                                costDto.setCostPrice(cost.getPrice());
                            }
                        }
                    }
                    break;
            }
        } catch (Exception e) {
            log.error("调用机票服务获取价格发生异常", e);
        }
        return costDto;
    }

    /* @MethodName: 获取 固定套票默认机票的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/19 14:44
     **/
    public BigDecimal getDefaultAirPrice(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        BigDecimal bd = BigDecimal.ZERO;
        //获取默认的 飞机票 产品 有返还
        List<SeasonFixedProductPackageAir> resultList = seasonFixedProductPackageAirMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageAir>().lambda().
                        eq(SeasonFixedProductPackageAir::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageAir::getPackageId, packageId)
        );
        boolean departFlag = true;
        boolean returnFlag = true;
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageAir result : resultList) {
                if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(result.getTripType())) {
                    bd.add(getAirProductPrice(result.getProductId(), departDate, userId, channelType).getCostPrice());
                    departFlag = false;
                }
                if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(result.getTripType())) {
                    bd.add(getAirProductPrice(result.getProductId(), arrDate, userId, channelType).getCostPrice());
                    returnFlag = false;
                }
            }
        }
        return bd;
    }

    @Override
    public List<SeasonFixedProductPackageAirDTO> getDefaultAirData(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        //获取默认的 飞机票 产品 有返还
        List<SeasonFixedProductPackageAir> resultList = seasonFixedProductPackageAirMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageAir>().lambda().
                        eq(SeasonFixedProductPackageAir::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageAir::getPackageId, packageId)
        );
        return getAirByAir(resultList, departDate, arrDate, userId, channelType);
    }

    @Override
    public List<SeasonFixedProductPackageAirDTO> getAirByPackageId(String tripType, Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        LambdaQueryWrapper<SeasonFixedProductPackageAir> qw = new QueryWrapper<SeasonFixedProductPackageAir>().lambda();
        qw.eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode()).
                eq(SeasonFixedProductPackageAir::getPackageId, packageId);
        if (StringUtils.isNotBlank(tripType)) {
            qw.eq(SeasonFixedProductPackageAir::getTripType, tripType);
        }
        //获取默认的 飞机票 产品 有返还
        List<SeasonFixedProductPackageAir> resultList = seasonFixedProductPackageAirMapper.selectList(qw);
        return getAirByAir(resultList, departDate, arrDate, userId, channelType);
    }

    private List<SeasonFixedProductPackageAirDTO> getAirByAir(List<SeasonFixedProductPackageAir> resultList, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        Multimap<String, SeasonFixedProductPackageAirDTO> map = LinkedHashMultimap.<String, SeasonFixedProductPackageAirDTO>create();
        List<SeasonFixedProductPackageAirDTO> resultDtoList = new ArrayList<>();
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageAir result : resultList) {
                SeasonFixedProductPackageAirDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageAirDTO.class);
                if (SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(result.getTripType())) {
                    resultDto.setCost(getAirProductPrice(result.getProductId(), departDate, userId, channelType).getCostPrice());
                }
                if (SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(result.getTripType())) {
                    resultDto.setCost(getAirProductPrice(result.getProductId(), arrDate, userId, channelType).getCostPrice());
                }
                map.put(result.getFlightNumber(), resultDto);
            }
        }
        for (String key : map.keySet()) {
            SeasonFixedProductPackageAirDTO flightDto = null;
            List<CabinClassDTO> CabinClassDTOs = new ArrayList<>();
            Collection<SeasonFixedProductPackageAirDTO> CabinClassVos = map.get(key);
            //遍历Multimap，得到每个航班下面的坐席的具体值:比如 一等，二等
            for (SeasonFixedProductPackageAirDTO value : CabinClassVos) {
                AirProductDetailDTO airProductDetailDTO = null;
                try {
                    airProductDetailDTO = iAirProductAppService.getProductDetail(value.getProductId(), departDate, userId);
                } catch (Exception e) {
                    log.error("调用机票服务获取详情发生异常", e);
                }
                if (null == flightDto) {
                    flightDto = EntityUtil.copy(value, SeasonFixedProductPackageAirDTO.class);
                    if (null != airProductDetailDTO) {
                        flightDto.setArrAirportId(airProductDetailDTO.getArrAirportId());
                        flightDto.setArrAirportName(airProductDetailDTO.getArrAirportName());
                        flightDto.setDepAirportId(airProductDetailDTO.getDepAirportId());
                        flightDto.setDepAirportName(airProductDetailDTO.getDepAirportName());
                    }
                }
                CabinClassDTO ccd = EntityUtil.copy(value, CabinClassDTO.class);
                if (null != airProductDetailDTO) {
                    ccd.setCabinName(airProductDetailDTO.getCabinName());
                    ccd.setBaggageStates(airProductDetailDTO.getAirProductReservationSettingsDataReq().getBaggageStates());
                    ccd.setBookingInformation(airProductDetailDTO.getAirProductReservationSettingsDataReq().getBookingInformation());
                }
                CabinClassDTOs.add(ccd);
            }
            CabinClassDTOs.sort(new Comparator<CabinClassDTO>() {
                @Override
                public int compare(CabinClassDTO o1, CabinClassDTO o2) {
                    return o2.getCost().compareTo(o1.getCost());
                }
            });
            flightDto.setCabinClassDTOs(CabinClassDTOs);
            resultDtoList.add(flightDto);
        }
        return resultDtoList;
    }


    /* @MethodName: 批量保存 机票信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/9 17:55
     **/
    @Override
    public void batchAirProduct(Long userId, Long packageId, List<SeasonFixedProductPackageAirReq> airReqList) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonFixedProductPackageAir> airList = airReqList.stream().map(
                airReq -> {
                    SeasonFixedProductPackageAir air = EntityUtil.copy(airReq, SeasonFixedProductPackageAir.class);
                    air.setCreateId(userId);
                    air.setPackageId(packageId);
                    air.setIsDeleted(IsDeletedCode.NO.getCode());
                    air.setId(IdWorker.getId());
                    air.setGmtCreate(now);
                    return air;
                }
        ).collect(Collectors.toList());
        seasonFixedProductPackageAirMapper.insertBatchSomeColumn(airList);
    }


    /* @MethodName: 获取固定套票 飞机票产品信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套id  packageId  打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 11:23
     **/
    @Override
    public List<SeasonFixedProductPackageAirDTO> getSeasonFixedProductAirDtoList(Long packageId) {
        List<SeasonFixedProductPackageAir> productPackageAirList = getAllSeasonFixedProductAirList(packageId);
        List<SeasonFixedProductPackageAirDTO> list = new LinkedList<>();
        if (null != productPackageAirList && productPackageAirList.size() > 0) {
            list = productPackageAirList.stream().map(
                    air -> {
                        SeasonFixedProductPackageAirDTO airDto = EntityUtil.copy(air, SeasonFixedProductPackageAirDTO.class);
                        return airDto;
                    }
            ).collect(Collectors.toList());
        }
        return list;
    }

    /* @MethodName: 获取所有机票信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/27 13:53
     **/
    List<SeasonFixedProductPackageAir> getAllSeasonFixedProductAirList(Long packageId) {
        List<SeasonFixedProductPackageAir> list = seasonFixedProductPackageAirMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageAir>().lambda()
                        .eq(SeasonFixedProductPackageAir::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode())
        );
        return list;
    }

    /* @MethodName: 删除原来的巴士产品
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/12 16:26
     **/
    @Override
    public void deletePreviousAir(Long userId, Long packageId) {
        LocalDateTime now = LocalDateTime.now();
        UpdateWrapper<SeasonFixedProductPackageAir> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("modified_id", userId);//修改人
        updateWrapper.set("is_deleted", IsDeletedCode.YES.getCode());//删除
        updateWrapper.set("gmt_modified", now);//修改时间
        updateWrapper.eq("package_id", packageId);
        seasonFixedProductPackageAirMapper.update(null, updateWrapper);

    }


    /* @MethodName: 获取机票差价信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 9:59
     **/
    @Override
    public List<SeasonFixedProductPackageAirDTO> getAirDifferencePrice(UpdatePackageProductReq req) {
        Long packageId = req.getPackageId();
        String journeyType = req.getJourneyType();//行程类型
        //查询日期 当是返程的时候 用结束日期
        LocalDate queryDate = req.getStartDate();
        if (SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(journeyType)) {
            queryDate = req.getEndDate();
        }
        List<SeasonFixedProductPackageAirDTO> list = new LinkedList<>();
        SeasonFixedProductPackageAirDTO airDTO = getSeasonFixedDefaultProductAir(packageId, journeyType, queryDate, req.getPassengerReqList(), req.getUserId());
        list.add(airDTO);
        BigDecimal flagCost = airDTO.getCost();
        List<SeasonFixedProductPackageAir> airList = getSeasonFixedProductAirList(packageId, journeyType);
        LocalDate finalQueryDate = queryDate;
        airList.stream().forEach(
                air -> {
                    Long shipProductId = air.getProductId();
                    SeasonFixedProductPackageAirDTO airDto = EntityUtil.copy(air, SeasonFixedProductPackageAirDTO.class);
                    BigDecimal airCost = getAirCost(shipProductId, finalQueryDate, req.getPassengerReqList(), req.getUserId());
                    airDto.setCost(airCost);
                    if (airCost.compareTo(BigDecimal.ZERO) == 0) {//表示没有库存
                        airDto.setPriceDifference("售罄");
                    } else {
                        airDto.setPriceDifference(String.valueOf(flagCost.subtract(airCost)));//减法
                    }
                    list.add(airDto);
                });


        return list;


    }

    /* @MethodName: 获取 不是默认 的机票 产品信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:20
     **/
    private List<SeasonFixedProductPackageAir> getSeasonFixedProductAirList(Long packageId, String journeyType) {
        List<SeasonFixedProductPackageAir> list = seasonFixedProductPackageAirMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageAir>().lambda()
                        .eq(SeasonFixedProductPackageAir::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageAir::getTripType, journeyType)
                        .eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageAir::getIsDefault, SeasonType.NO_DEFAULT.getCode())
        );
        return list;

    }

    /* @MethodName: 获取固定套票 飞机票的默认价
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:06
     **/
    private SeasonFixedProductPackageAirDTO getSeasonFixedDefaultProductAir(Long packageId, String
            journeyType, LocalDate queryDate, List<PassengerReq> passengerReqList, Long userId) {
        SeasonFixedProductPackageAir air = seasonFixedProductPackageAirMapper.selectOne(
                new QueryWrapper<SeasonFixedProductPackageAir>().lambda()
                        .eq(SeasonFixedProductPackageAir::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageAir::getTripType, journeyType)
                        .eq(SeasonFixedProductPackageAir::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageAir::getIsDefault, SeasonType.YES_DEFAULT.getCode())
        );

        SeasonFixedProductPackageAirDTO airDTO = EntityUtil.copy(air, SeasonFixedProductPackageAirDTO.class);
        BigDecimal airCost = getAirCost(airDTO.getProductId(), queryDate, passengerReqList, userId);
        airDTO.setCost(airCost);
        if (airCost.compareTo(BigDecimal.ZERO) == 0) {
            airDTO.setPriceDifference("售罄");
        } else {
            airDTO.setPriceDifference("0");
        }
        return airDTO;

    }

    /* @MethodName: 获取飞机票的成本
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:12
     **/
    private BigDecimal getAirCost(Long productId, LocalDate queryDate, List<PassengerReq> passengerReqList, Long
            userId) {
//        ProductPriceReq queryReq = new ProductPriceReq();
//        queryReq.setQueryDate(queryDate);
//        queryReq.setProductId(productId);//飞机产品id
//        queryReq.setUserId(userId);
//        queryReq.setPassengerReqList(passengerReqList);
//        //获取机票的价格
        return BigDecimal.ZERO;
    }


    /* @MethodName: 获取固定套票 飞机票产品信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套id  packageId  打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 11:23
     **/
    private List<SeasonFixedProductPackageAir> getgetSeasonFixedProductAirList(Long packageId) {
        QueryWrapper<SeasonFixedProductPackageAir> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("package_id", packageId);
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());

        return seasonFixedProductPackageAirMapper.selectList(queryWrapper);
    }
}
